/*实验二、
1.
// 输出当前文件路径和目录
console.log("__filename:", __filename);
console.log("__dirname:", __dirname);
// 使用 path 拼接
const path = require("path");
const viewPath = path.join(__dirname, "views", "index.html");
console.log("拼接后的视图路径:", viewPath);
const util = require("util");
2.
const user = {
name: "Alice",
age: 20,
qq: "123456"
        };
// %s 输出字符串
        console.log("Name: %s", user.name);
// %d 输出数字
console.log("Age: %d", user.age);
// %j 输出 JSON
console.log("User JSON: %j", user);
3.
time-sample.js
console.time("耗时任务");
let sum = 0;
for (let i = 0; i < 1e7; i++) {
sum += i;
}
        console.timeEnd("耗时任务");
多运行几次，时间会有轻微差异
4.
console.log("CPU 架构:", process.arch);
console.log("操作系统:", process.platform);
console.log("进程 ID:", process.pid);
console.log("Node 可执行路径:", process.execPath);
console.log("内存使用情况:", process.memoryUsage());
5.
const args = process.argv.slice(2);
function printHelp() {
    console.log("用法: node calc.js <表达式>");
    console.log("例如: node calc.js \"2+3*4\"");
}
if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
printHelp();
} else {
        const expr = args[0];
        try {
        // eval 有安全风险，这里仅用于实验
        const result = eval(expr);
    if (typeof result === "number") {
        console.log("结果:", result);
    } else {
            console.log("错误: 非法的数学表达式");
    }
            } catch (e) {
        console.log("错误: 非法的数学表达式");
  }
          }
6.
const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
            output: process.stdout
});
        const user = {};
        rl.question("请输入姓名: ", (name) => {
user.name = name;
  rl.question("请输入邮箱: ", (email) => {
user.email = email;
    rl.question("请输入QQ号: ", (qq) => {
user.qq = qq;
      rl.question("请输入手机号码: ", (phone) => {
user.phone = phone;
        console.log("用户信息:", user);
        rl.close();
      });
              });
              });
              });
        7.
function Bomb(name) {
    this.name = name;
    this.timer = null;
}

Bomb.prototype.start = function () {
    this.timer = setTimeout(() => {
            console.log(this.name, "Boom!");
  }, 3000);
};

Bomb.prototype.clear = function () {
    if (this.timer) {
        clearTimeout(this.timer);
        console.log(this.name, "已解除");
    }
};
// 测试
const b1 = new Bomb("炸弹1");
const b2 = new Bomb("炸弹2");
b1.start();
b2.start();
setTimeout(() => {
        b2.clear();
}, 1000);*/


/*
实验三、
程序① 01-file-dir-name.js
// 输出文件名和目录名
console.log("__filename:", __filename);
console.log("__dirname:", __dirname);

// 使用 path 拼接视图路径
const path = require("path");
const viewPath = path.join(__dirname, "views", "index.html");
console.log("视图文件路径:", viewPath);

程序② base64 编解码
// base64 编码解码
const base64Str = 'emhhbmdzYW46MTIzNDU2'; // 'zhangsan:123456' 的 base64

// 解码
        const buf = Buffer.from(base64Str, 'base64');
console.log("解码结果:", buf.toString());

// 再编码
        const str = 'lisi:654321';
        const encoded = Buffer.from(str).toString('base64');
console.log("编码结果:", encoded);

程序③ 计时器示例
// 使用 setTimeout / setInterval
let count = 0;

const timer = setInterval(() => {
count++;
        console.log("第 %d 次执行", count);

  if (count >= 5) {
clearInterval(timer);
    console.log("定时器已停止");
  }
          }, 1000);

程序④ process 信息
// 输出进程信息
console.log("Node 可执行路径:", process.execPath);
console.log("平台:", process.platform);
console.log("进程 PID:", process.pid);
console.log("当前目录:", process.cwd());
        console.log("内存使用情况:", process.memoryUsage());

程序⑤ 命令行参数
// 获取命令行参数
const args = process.argv.slice(2);

if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
        console.log("用法: node 程序名.js <表达式>");
  console.log("示例: node calc.js \"3*7+2\"");
} else {
        try {
        const result = eval(args[0]);  // 实验用，注意安全风险
    if (typeof result === "number") {
        console.log("结果:", result);
    } else {
            console.log("错误: 非法表达式");
    }
            } catch (err) {
        console.log("错误: 非法表达式");
  }
          }

程序⑥ readline 交互输入
const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
            output: process.stdout
});

        const user = {};

        rl.question("请输入姓名: ", (name) => {
user.name = name;

  rl.question("请输入邮箱: ", (email) => {
user.email = email;

    rl.question("请输入QQ号: ", (qq) => {
user.qq = qq;

      rl.question("请输入手机号码: ", (phone) => {
user.phone = phone;

        console.log("用户信息:", user);
        rl.close();
      });
              });
              });
              });*/

/*实验四、
程序① Dog 构造函数与事件
文件：dog.js
const EventEmitter = require("events");
function Dog(name, energy) {
    this.name = name;
    this.energy = energy;
    EventEmitter.call(this);
}

Dog.prototype = Object.create(EventEmitter.prototype);

Dog.prototype.start = function () {
  const interval = setInterval(() => {
    if (this.energy > 0) {
        this.emit("bark");
        this.energy--;
    } else {
        clearInterval(interval);
    }
  }, 1000);
};

// 测试
const taidi = new Dog("taidi", 5);
const zangao = new Dog("zangao", 3);

taidi.on("bark", () => {
        console.log(taidi.name, "barked, energy =", taidi.energy);
});
        zangao.on("bark", () => {
        console.log(zangao.name, "barked, energy =", zangao.energy);
});

        taidi.start();
zangao.start();


运行效果：

        taidi barked, energy = 4
        zangao barked, energy = 2
        taidi barked, energy = 3
        zangao barked, energy = 1
...


直到 energy 为 0 停止。

程序② Radio 电台事件

文件：radio.js

const EventEmitter = require("events");

function Radio(name, freq) {
    this.name = name;
    this.freq = freq;
    EventEmitter.call(this);
}

Radio.prototype = Object.create(EventEmitter.prototype);

Radio.prototype.open = function () {
    console.log(this.name, this.freq, "opened");
    setTimeout(() => {
            this.emit("play", "lalalala");
  }, 2000);
};

Radio.prototype.close = function () {
    this.emit("close");
};

// 测试
const radio = new Radio("music radio", "FM 106.7");

radio.on("play", (music) => {
        console.log(music);
  radio.close();
});

        radio.on("close", () => {
        console.log("radio closed");
});

        radio.open();


        运行效果：

        music radio FM 106.7 opened
        （2秒后）
        lalalala
        radio closed*/

/*实验五、
程序① 可读流

文件：readStream.js

const fs = require("fs");

// 创建可读流
const rs = fs.createReadStream("input.txt", { encoding: "utf-8" });

rs.on("open", () => {
  console.log("文件打开");
});

rs.on("data", (chunk) => {
  console.log("读取到数据:", chunk);
});

rs.on("end", () => {
  console.log("文件读取完毕");
});

rs.on("close", () => {
  console.log("文件关闭");
});

程序② 可写流

文件：writeStream.js

const fs = require("fs");

// 创建可写流
const ws = fs.createWriteStream("output.txt");

ws.write("Hello Node.js Stream!\n");
ws.write("写入第二行内容\n");
ws.end();

ws.on("finish", () => {
  console.log("写入完成");
});

程序③ 管道示例

文件：pipeStream.js

const fs = require("fs");

// 从 input.txt 读取，通过管道写入到 copy.txt
const rs = fs.createReadStream("input.txt");
const ws = fs.createWriteStream("copy.txt");

rs.pipe(ws);

ws.on("finish", () => {
  console.log("文件复制完成");
});

程序④ stream.doc 内容（文字说明）

流的概念：流（Stream）是数据传输的一种方式，数据像流水一样从一端流向另一端。
工作过程：流是基于事件的，常见事件有 data（有数据可读）、end（数据读取结束）、finish（写入完成）、error（出错）等。通过监听这些事件可以控制数据的流动。
应用场景：文件的读取与写入、网络请求与响应、视频音频播放、数据压缩和解压缩等。
 */

/*实验六、
程序① 读取文件内容

文件：readFile.js

const fs = require("fs");

// 异步读取
fs.readFile("input.txt", "utf-8", (err, data) => {
  if (err) {
    return console.error("读取失败:", err);
  }
  console.log("异步读取结果:", data);
});

// 同步读取
try {
  const data = fs.readFileSync("input.txt", "utf-8");
  console.log("同步读取结果:", data);
} catch (err) {
  console.error("同步读取失败:", err);
}

程序② 写入文件

文件：writeFile.js

const fs = require("fs");

const content = "Hello Node.js 文件系统写入测试\n";

// 异步写入
fs.writeFile("output.txt", content, (err) => {
  if (err) {
    return console.error("写入失败:", err);
  }
  console.log("异步写入成功");

  // 验证写入结果
  fs.readFile("output.txt", "utf-8", (err, data) => {
    if (err) throw err;
    console.log("写入文件内容:", data);
  });
});

// 同步写入
try {
  fs.writeFileSync("output2.txt", "这是同步写入的内容\n");
  console.log("同步写入成功");
} catch (err) {
  console.error("同步写入失败:", err);
}

任务③ 追加内容到文件

文件：appendFile.js

const fs = require("fs");

const addContent = "追加的一行内容\n";

fs.appendFile("output.txt", addContent, (err) => {
  if (err) {
    return console.error("追加失败:", err);
  }
  console.log("内容追加成功");
});

任务④ 删除文件

文件：deleteFile.js

const fs = require("fs");

fs.unlink("output2.txt", (err) => {
  if (err) {
    return console.error("删除失败:", err);
  }
  console.log("文件删除成功");
});

任务⑤ 文件/目录操作综合

文件：fileOps.js

const fs = require("fs");

// 创建目录
fs.mkdir("testDir", (err) => {
  if (err && err.code !== "EEXIST") {
    return console.error("创建目录失败:", err);
  }
  console.log("目录创建成功或已存在");

  // 在目录里创建文件
  fs.writeFile("testDir/hello.txt", "目录文件内容\n", (err) => {
    if (err) throw err;
    console.log("文件写入成功");

    // 读取文件
    fs.readFile("testDir/hello.txt", "utf-8", (err, data) => {
      if (err) throw err;
      console.log("读取目录文件内容:", data);

      // 删除文件
      fs.unlink("testDir/hello.txt", (err) => {
        if (err) throw err;
        console.log("文件删除成功");

        // 删除目录
        fs.rmdir("testDir", (err) => {
          if (err) throw err;
          console.log("目录删除成功");
        });
      });
    });
  });
});
 */


/*实验九
程序① 爬取猫眼电影并展示
（需要安装 axios + cheerio）

const http = require("http");
const axios = require("axios");
const cheerio = require("cheerio");

const url = "https://maoyan.com/films";

http.createServer(async (req, res) => {
  try {
    const { data } = await axios.get(url, { headers: { "User-Agent": "Mozilla/5.0" } });
    const $ = cheerio.load(data);
    let list = [];
    $(".movie-item").each((i, el) => {
      const name = $(el).find(".name a").text();
      const id = $(el).find(".name a").attr("data-val");
      const score = $(el).find(".integer").text() + $(el).find(".fraction").text();
      list.push({ name, id, score });
    });
    res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
    res.write("<h1>猫眼电影</h1><ul>");
    list.forEach(m => res.write(`<li>${m.name} - ${m.score}</li>`));
    res.end("</ul>");
  } catch (e) {
    res.end("抓取失败:" + e.message);
  }
}).listen(8081);


程序② clientPost.js

const http = require("http");

const [username, password] = process.argv.slice(2);
const data = JSON.stringify({ username, password });

const options = {
  hostname: "localhost",
  port: 8081,
  path: "/login",
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Content-Length": Buffer.byteLength(data)
  }
};

const req = http.request(options, (res) => {
  res.on("data", (chunk) => console.log(chunk.toString()));
});
req.write(data);
req.end();


程序② myServer.js

const http = require("http");
const fs = require("fs");

http.createServer((req, res) => {
  if (req.method === "POST" && req.url === "/login") {
    let body = "";
    req.on("data", chunk => (body += chunk));
    req.on("end", () => {
      const { username, password } = JSON.parse(body);
      fs.readFile("data.json", "utf-8", (err, data) => {
        if (err) return res.end("读取失败");
        const users = JSON.parse(data);
        const ok = users.find(u => u.username === username && u.password === password);
        res.end(ok ? "登录成功" : "用户名、密码不正确");
      });
    });
  } else {
    res.end("请求路径错误");
  }
}).listen(8081);


data.json 示例

[
  { "username": "admin", "password": "123456" },
  { "username": "test", "password": "111111" }
]
 */

